package com.doraro.platform.common.exception;

import com.doraro.platform.common.utils.Result;
import com.doraro.platform.common.utils.ValidationUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class RestExceptionHandler {


    /**
     * 处理不符合@Vaild 所抛出的异常
     *
     * @param ex the ex
     * @return the response entity
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result invalidInput(MethodArgumentNotValidException ex) {
        return new Result().error(HttpStatus.BAD_REQUEST,
                ValidationUtil.fromBindingErrors(ex.getBindingResult()));
    }

    /**
     * 缺少参数处理
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result missParamException(MissingServletRequestParameterException ex) {
        return new Result().error(HttpStatus.BAD_REQUEST, ex.getMessage());
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public Result duplicateKeyException(DuplicateKeyException ex) {
        return new Result().error(HttpStatus.BAD_REQUEST, "请勿重复插入");
    }
    /**
     * 参数值非法异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result invalidInput(HttpMessageNotReadableException ex) {
        String msg = "参数值非法异常";
        if (ex.getCause() instanceof JsonProcessingException) {
            msg = "JSON格式错误";
        }
        return new Result().error(HttpStatus.BAD_REQUEST, msg);
    }

    /**
     * shiro 权限异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler({AuthorizationException.class})
    public Result handleAuthorizationException(AuthorizationException e) {
        return new Result().error(HttpStatus.FORBIDDEN, "无权查看");
    }

    @ExceptionHandler({UnsupportedTokenException.class})
    public Result handleUnsupportedTokenException(UnsupportedTokenException e) {
        return new Result().error(HttpStatus.UNAUTHORIZED, e.getMessage());
    }
    /**
     * 处理业务逻辑异常
     */
    @ExceptionHandler(ApiGlobalException.class)
    public Result resourcesNotFound(ApiGlobalException ex) {
        return new Result().error(ex);
    }

    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Result httpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException ex) {
        return new Result().error(HttpStatus.BAD_REQUEST, ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result unknownException(Exception ex) {
        log.warn("exception: {}, message: {}", ex.getClass(), ex.getMessage());
        ex.printStackTrace();
        return new Result().error();
    }

}
